package ejb.facade;

import ejb.dao.WeatherDAO;
import ejb.entities.Event;
import ejb.entities.WeatherForecast;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import net.aksingh.java.api.owm.DailyForecastData;
import net.aksingh.java.api.owm.OpenWeatherMap;
import org.json.JSONException;

@Stateless
public class WeatherFacadeImp implements WeatherFacade{
    
    @EJB
    private WeatherDAO weatherDAO;
    
        @Override
	public void save(WeatherForecast u) {
		weatherDAO.save(u);
	}

	@Override
	public WeatherForecast update(WeatherForecast u) {
		// TODO Auto-generated method stub
		return weatherDAO.update(u);
	}

	@Override
	public void delete(WeatherForecast u) {
		// TODO Auto-generated method stub
		weatherDAO.delete(u);

	}

	@Override
	public WeatherForecast find(int entityID) {
		// TODO Auto-generated method stub
		return weatherDAO.find(entityID);
	}

	@Override
	public List<WeatherForecast> findAll() {
		// TODO Auto-generated method stub
		return weatherDAO.findAll();
	}
        
        @Override
        public WeatherForecast getDailyWeatherForecast(String city, Date dataforecast, boolean start){
                WeatherForecast weathFore = new WeatherForecast();
                DateFormat stringFormat = new SimpleDateFormat("yyyy/MM/dd");
                Calendar cal = Calendar.getInstance();
                    //Add one day to date start search to take next prevision if after 13:00
                    Calendar c = Calendar.getInstance(); 
                    c.setTime(dataforecast); 
                    c.add(Calendar.DATE, 1);
                    dataforecast = c.getTime();
                String todayStr = stringFormat.format(cal.getTime());
                String forecastStr = stringFormat.format(dataforecast);
                Date todayDate = new Date();
                Date forecastDate = new Date();
                try {
                    todayDate = stringFormat.parse(todayStr);
                    forecastDate = stringFormat.parse(forecastStr);
                } catch (ParseException ex) {
                    Logger.getLogger(WeatherFacadeImp.class.getName()).log(Level.SEVERE, null, ex);
                }
                
            try{
             // declaring object of "OpenWeatherMap" class
               OpenWeatherMap owm = new OpenWeatherMap("");

                long diff = forecastDate.getTime() - todayDate.getTime();
                long days=TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
        
                DailyForecastData datafor;
                if(days == 0) days = 1;
                        else if(days < 0) days = days*(-1);
                
                
                datafor=owm.dailyForecastByCityName(city, (byte)days);
                
                if(datafor.getCity_Object().getCityName()== null) {
                        if(!start)
                            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Fatal!", "City not found! Weather Forecast not available!"));
                            weathFore.setLastupdate(cal.getTime());
                            weathFore.setAvailable(false);
                    } else if(datafor.getCity_Object().getCityName().equals(city)){
                        if(datafor.getForecast_List_Count()>=days-1){
                            DailyForecastData.Forecast forec =datafor.getForecast_List().get((int)days-1);
                            if(forec!=null){
                                weathFore.setDateforecast(forec.getDateTime());
                                weathFore.setHumidity(forec.getHumidity());
                                weathFore.setPressure(forec.getPressure());
                                weathFore.setPerclouds(forec.getPercentageOfClouds());
                                weathFore.setWindspeed(forec.getWindSpeed());
                                weathFore.setWindded(forec.getWindDegree());
                                DailyForecastData.Forecast.Temperature tempstate = forec.getTemperature_Object();
                                weathFore.setMaxtemp(fahrenheitToCelsius(tempstate.getMaximumTemperature()));
                                weathFore.setMintemp(fahrenheitToCelsius(tempstate.getMinimumTemperature()));
                            
                                //Weather State
                                List<DailyForecastData.Forecast.Weather> listWeather= forec.getWeather_List();
                                weathFore.setWeatherCode(listWeather.get(0).getWeatherCode());
                                weathFore.setWeatherDesc(listWeather.get(0).getWeatherDescription());
                                weathFore.setWeatherCodeStr(listWeather.get(0).getWeatherName());
                                weathFore.setWeatherString(listWeather.get(0).getWeatherIconName());
                                weathFore.setLastupdate(cal.getTime());
                                weathFore.setAvailable(true);
                            }else{
                                weathFore.setLastupdate(cal.getTime());
                                weathFore.setAvailable(false); 
                            }
                        }else{
                            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Fatal!", "Weather Forecast not available fot that day!"));
                            weathFore.setLastupdate(cal.getTime());
                            weathFore.setAvailable(false);     
                        }
                    }else{
                        if(!start)
                            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Fatal!", "City not found! Weather Forecast not available!"));
                                weathFore.setLastupdate(cal.getTime());
                                weathFore.setAvailable(false);
                    }
             }catch(IOException | JSONException e){
                 weathFore.setLastupdate(cal.getTime());
                 weathFore.setAvailable(false); 
             }    
            
        return weathFore;
    }
        
        public float fahrenheitToCelsius(float f){
            return((f - 32)*5)/9;
        }
        
}